package com.funtl.oauth2.server.config;

import com.funtl.oauth2.server.config.service.UserDetailsServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * @author: Han.Fu
 * @TIME: 2019/7/14  15:33
 * @Description: 基于RBAC模型, 和数据库对接上了
 */
@Configuration // 注解类
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
// @EnableGlobalMethodSecurity 使用注解的规范, 全局方法的拦截
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        return new UserDetailsServiceImpl();
    }

    //oauth2.0不允许明文, 密码需要加密
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    //用户的认证与授权,就基于RBAC模型(自定义用户认证)并且和数据库对接上了
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // (1) 在内存模型中快速进行数据交互, 仅仅只是为了方便Demo的演示
        /*auth.inMemoryAuthentication()
                .withUser("admin").password(passwordEncoder().encode("123456")).roles("ADMIN")
                .and()
                .withUser("user").password(passwordEncoder().encode("123456")).roles("USER");*/


        // (2) 验证 此 userDetailsService 的权限
        //将我们的模型和oauth2.0的模型进行对接
        auth.userDetailsService(userDetailsService());
    }


    /*
    * /oauth/authorize：授权端点
      /oauth/token：令牌端点
      /oauth/confirm_access：用户确认授权提交端点
      /oauth/error：授权服务错误信息端点
      /oauth/check_token：用于资源服务访问的令牌解析端点
      /oauth/token_key：提供公有密匙的端点，如果你使用 JWT 令牌的话
    * */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/oauth/check_token");
    }
}
